package cn.com.cetccst.mdm.engine;

import static android.content.Context.DEVICE_POLICY_SERVICE;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;

import java.util.List;

import cn.com.cetccst.tools.log.CommonLogger;

public class BaseMDMEngine implements IMDMEngine {
    public static final byte[] token = "12345678901234561234567890123456".getBytes();
    protected Context context;
    protected ComponentName adminComponent;
    protected String fileProviderAuthority;
    protected Callback logger;
    protected DevicePolicyManager devicePolicyManager;
    protected PackageManager packageManager;

    public BaseMDMEngine(Context context) {
        this.context = context;
        devicePolicyManager = context.getSystemService(DevicePolicyManager.class);
        packageManager = context.getPackageManager();
        checkAndSetResetPasswordToken(context);
    }

    @Override
    public void config(ComponentName adminComponent, String fileProviderAuthority, Callback logger) {
        this.adminComponent = adminComponent;
        this.fileProviderAuthority = fileProviderAuthority;
        this.logger = logger;
    }

    @Override
    public boolean isActiveDeviceAdmin() {
        return devicePolicyManager.isAdminActive(adminComponent);
    }

    @Override
    public boolean removeDeviceAdmin() {
        try {
            devicePolicyManager.clearDeviceOwnerApp(context.getPackageName());
        } catch (Exception e) {
        }
        try {
            devicePolicyManager.removeActiveAdmin(adminComponent);
        } catch (Exception e) {
        }
        return true;
    }

    @Override
    public boolean setActiveDeviceAdmin(Activity activity) {
        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminComponent);
        //intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, getString(R.string.add_admin_extra_app_text));
        activity.startActivityForResult(intent, 10000);
        return true;
    }

    @Override
    public void controlBluetooth(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isBluetoothControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setBluetoothWhiteList(List<String> whitList) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getBluetoothWhiteList() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlCamera(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isCameraControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlWifi(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isWifiControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setWifiWhiteList(List<String> whiteList) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getWifiWhitList() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlMicroPhone(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isMicroPhoneControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlExternalStorage(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isExternalStorageControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlScreenShot(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isScreenShotControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlNFC(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isNFCControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlMobileHotSpot(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isMobileHotSpotControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlCallout(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isCalloutControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlSms(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isSmsControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlMobileData(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isMobileDataControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlVolumeDown(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isVolumeDownControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlAutoTime(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isAutoTimeControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlUsbData(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isUsbDataControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlUsbDebug(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isUsbDebugControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlRestoreFactory(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isRestoreFactoryControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlSystemUpgrade(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isSystemUpgradeControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlGPS(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isGPSControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlForceGPS(boolean enabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isForceGPSControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlUnknownSource(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isUnknownSourceControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setUnknownSourceWhiteList(List<String> packages) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getUnknownSourceWhiteList() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlCopyPaste(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isCopyPasteControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlFingerPrint(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isFingerPrintControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setDisallowRunningApps(List<String> packageNames, boolean isBlock) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getDisallowRunningApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setAllowRunningApps(List<String> packageNames, boolean isBlock) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getAllowRunningApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void installPackage(String apkPath) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void uninstallPackage(String packageName) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void formatSDCard() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void factoryReset() {
        if (devicePolicyManager.isAdminActive(adminComponent)) {
            devicePolicyManager.wipeData(0);
        }
    }

    @Override
    public boolean setInstallSourceApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getInstallSourceApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setNetworkWhiteListApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getNetworkWhiteListApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setNetworkBlackListApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getNetworkBlackListApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setNetworkWhiteListAddress(List<String> address) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getNetworkWhiteListAddress() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setNetworkBlackListAddress(List<String> address) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getNetworkBlackListAddress() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setKeepLiveApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getKeepLiveApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setUninstallblockApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getUninstallblockApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setInstallblockApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getInstallblockApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }


    @Override
    public boolean setSuperApps(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getSuperApps() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean setDevicePassword(String password) {
        boolean succeed = false;
        try {
            if (devicePolicyManager.isAdminActive(adminComponent)) {
                succeed = devicePolicyManager.resetPasswordWithToken(adminComponent, password, token, 0);
                devicePolicyManager.lockNow();
                if (TextUtils.isEmpty(password)) {
                    devicePolicyManager.setKeyguardDisabledFeatures(adminComponent, DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE);
                } else {
                    devicePolicyManager.setKeyguardDisabledFeatures(adminComponent, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
                }
            }
        } catch (Exception e) {
            CommonLogger.error("can not reset device password", e);
        }

        return succeed;
    }

    @Override
    public boolean setPermittedAccessibility(List<String> packageNames) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public List<String> getPermittedAccessibilityServices() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public String getName() {
        return "Base";
    }

    @Override
    public void controlSingleApp(boolean enabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isSingleAppControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean controlDeviceOwner(boolean enable) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isDeviceOwnerControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean controlRemoveDeviceAdmin(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isRemoveDeviceAdminControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void controlAddUser(boolean disabled) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public boolean isAddUserControlled() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void shutdown() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void reboot() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public void powerOnAt(long time) {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    @Override
    public String getSN() {
        throw new NotSupportException(new Object() {
        }.getClass().getEnclosingMethod().getName());
    }

    public boolean checkAndSetResetPasswordToken(Context context) {
        try {
            DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService(DEVICE_POLICY_SERVICE);
            if (devicePolicyManager.isDeviceOwnerApp(context.getPackageName())) {
                if (!devicePolicyManager.isResetPasswordTokenActive(adminComponent)) {
                    boolean succeed = devicePolicyManager.setResetPasswordToken(adminComponent, token);
                    Log.e("MDM", "checkAndSetResetPasswordToken " + succeed);
                    return true;
                }
            }
        } catch (Exception e) {
        }
        return false;
    }

    public String parsePackageName(String apkPath) {
        String packageName = "";
        if (apkPath != null) {
            int beginIndex = apkPath.lastIndexOf("/");
            String newString = apkPath.substring(beginIndex + 1);
            int endIndex = newString.indexOf("_");
            if (endIndex < 0) {
                endIndex = newString.lastIndexOf(".");
            }
            packageName = newString.substring(0, endIndex);
        }
        return packageName;
    }

    public interface Callback {
        void log(String msg);
    }
}
